﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DGui;
using GameRobot;
using GameRobotControl;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using RobotGameData;

namespace RobotGame.ScreenManagers
{
    public class GameTwoScreen:GameScreen
    {
        Viewport playerOneViewport;
        Viewport playerTwoViewport;
        private Texture2D blank;

        private MapEngine mapEngine;
        private Cameras camera;

        // private InputState input;
        private SpriteFont font;

        private PathFinder pathFinder;
        Vector2 positionMouse = new Vector2();

        private frmTwoView twoView;

        private RobotManager _robotManager = new RobotManager();
        GameInput _gameInput = new GameInput();

        public RobotManager RobotManager
        {
            get { return _robotManager; }
            set { _robotManager = value; }
        }


        public override void LoadContent()
        {
           blank = new Texture2D(ScreenManager.GraphicsDevice, 1, 1);
            blank.SetData(new[] { Color.White });

            // Create the viewports
            playerOneViewport = new Viewport
            {
                MinDepth = 0,
                MaxDepth = 1,
                X = 0,
                Y = 0,
                Width = ScreenManager.GraphicsDevice.Viewport.Width,
                Height = ScreenManager.GraphicsDevice.Viewport.Height / 2,
            };
            playerTwoViewport = new Viewport
            {
                MinDepth = 0,
                MaxDepth = 1,
                X = 0,
                Y = ScreenManager.GraphicsDevice.Viewport.Height / 2,
                Width = ScreenManager.GraphicsDevice.Viewport.Width,
                Height = ScreenManager.GraphicsDevice.Viewport.Height / 2,
            };


            ContentManager content = ScreenManager.Game.Content;

            //  input = new InputState();
            mapEngine = new MapEngine();

            font = content.Load<SpriteFont>("Fonts\\menufont");

            String strPath = "Content\\Maps\\Map1.xml";
            mapEngine.Map = mapEngine.LoadMap(content, strPath);


            camera = new Cameras(new Vector2(mapEngine.Map.MapDimensions.X, mapEngine.Map.MapDimensions.X), new Vector2(mapEngine.Map.TileSize.X, mapEngine.Map.TileSize.Y), new Vector2(playerOneViewport.Width, playerOneViewport.Height));

            twoView = new frmTwoView(this);
            twoView.LoadContent(playerTwoViewport);

            // init load robot
            RobotControlSetting._dllpath = @"F:\Projects\RobotGame\RobotGame\bin\x86\Debug\RobotDLL";
            string assetName = "Textures\\Players\\Warrior1WalkLeft";
            RobotManager.AddRobot(new SampleRobot(assetName, new Vector2(600, 600), new Vector2(138f, 192f), 6));
            RobotManager.LoadContent(content);
            LoadFunctionFromRobot();

            camera.FocusOn(RobotManager._listRobot[0]);

            positionMouse = new Vector2(600, 600);
            mapEngine.Map.StartTile = mapEngine.Map.PointToTile( RobotManager._listRobot[0].Position);
            mapEngine.Map.EndTile = mapEngine.Map.PointToTile(RobotManager._listRobot[0].Position);
            pathFinder = new PathFinder();
            pathFinder.Initialize(mapEngine.Map);
            pathFinder.Reset();
            pathFinder.LoadContent(content);
            RobotManager._listRobot[0].Position = mapEngine.Map.MapToWorld(mapEngine.Map.StartTile, true);

            base.LoadContent();
        }

        

        private void LoadFunctionFromRobot()
        {
            _gameInput.game_message.message = messagedef.ChangeToChedulingControl;
            RobotManager.Update(_gameInput);
            _gameInput.game_message.message = messagedef.None;

            List<string> lbm = RobotManager.GetListBaseMethod(0);
            if (lbm != null)
            {
                int n = lbm.Count;
                for (int i = 0; i < n; i++)
                {
                    twoView.BasicFunction.AddItem(lbm[i].Substring(lbm[i].IndexOf(" ") + 1),null);
                    twoView.BasicFunction.Tag = lbm[i];
                    //twoView.BasicFunction.SelectedIndex = 0;
                }
            }

            List<string> lmm = RobotManager.GetListMetaMethod(0);
            if (lmm != null)
            {
                int n = lmm.Count;
                for (int i = 0; i < n; i++)
                {
                    twoView.UserFunction.AddItem(lmm[i].Substring(lmm[i].IndexOf(" ") + 1), null);
                    //twoView.UserFunction.SelectedIndex = 0;
                }
            }

        }

        public override void UnloadContent()
        {
            base.UnloadContent();
        }
        public override void HandleInput(RobotGameData.InputState input)
        {
            base.HandleInput(input);
            RobotManager._listRobot[0].HandleInput(input);
            camera.Update(input);
            

            if (pathFinder.SearchStatus == SearchStatus.PathFound && !RobotManager._listRobot[0].Moving)
            {
                foreach (Point point in pathFinder.FinalPath())
                {
                    RobotManager._listRobot[0].Waypoints.Enqueue(mapEngine.Map.MapToWorld(point, true));
                }
                RobotManager._listRobot[0].Moving = true;
            }

            if (input.IsLeftButtonPress()
                && pathFinder.SearchStatus != SearchStatus.Searching
                && CollisionWithView(camera.VisibleArea))
            {
                positionMouse = new Vector2(input.CurrentMousestate.X, input.CurrentMousestate.Y);
                Vector2 plus = new Vector2(camera.VisibleArea.Width - 1024, camera.VisibleArea.Height - 384);
                Point mouseTile = mapEngine.Map.PointToTile(positionMouse + plus);

                if (mapEngine.Map.PointToTile(RobotManager._listRobot[0].Position) == mapEngine.Map.EndTile)
                {
                    mapEngine.Map.StartTile = mapEngine.Map.EndTile;
                    mapEngine.Map.EndTile = mouseTile;
                    pathFinder.Reset();
                    pathFinder.SearchStatus = SearchStatus.Searching;
                    RobotManager._listRobot[0].Moving = false;
                }
                else
                {
                    mapEngine.Map.StartTile = mapEngine.Map.EndTile;
                    mapEngine.Map.EndTile = mouseTile;
                    pathFinder.Reset();
                    pathFinder.SearchStatus = SearchStatus.Searching;
                    RobotManager._listRobot[0].Moving = false;
                }

            }
            
        }

        private bool CollisionWithView(Rectangle viewport)
        {
            if (positionMouse.X >= viewport.X
                && positionMouse.X <= viewport.Width
                 && positionMouse.Y >= viewport.Y
                 && positionMouse.Y <= viewport.Height)
            {
                return true;
            }
            return false;
        }
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
            twoView.Update(gameTime);
            //RobotManager._listRobot[0].Update(gameTime);
            RobotManager.Update(new GameInput());

            //CheckCollisions();

            //CheckCollision();

            pathFinder.Update(gameTime);

            if (pathFinder.SearchStatus == SearchStatus.NoPath)
            {
                pathFinder.Reset();
            }
           
        }
        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            ScreenManager.GraphicsDevice.Clear(Color.CornflowerBlue);
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            Viewport oldViewport = ScreenManager.GraphicsDevice.Viewport;
            ScreenManager.GraphicsDevice.Viewport = playerOneViewport;

          
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.None, camera.Matrix);
            mapEngine.DrawLayers(spriteBatch, true, true, false, camera.VisibleArea);
            //World.Player.Draw(spriteBatch);
            RobotManager._listRobot[0].Draw(spriteBatch);

            mapEngine.DrawLayers(spriteBatch, false, false, true, camera.VisibleArea);
            mapEngine.DrawColision(spriteBatch, camera.VisibleArea, ScreenManager.GraphicsDevice);


            pathFinder.Draw(spriteBatch);

            spriteBatch.End();

            ScreenManager.GraphicsDevice.Viewport = oldViewport;

            spriteBatch.Begin();
            spriteBatch.DrawString(font, "Position: " + mapEngine.Map.PointToTile( RobotManager._listRobot[0].Position).ToString(), new Vector2(0f, 20f), Color.Yellow);

            spriteBatch.DrawString(font, "Camera: " + camera.VisibleArea.ToString(), new Vector2(0f, 100f), Color.Red);
            Vector2 plus = new Vector2(camera.VisibleArea.Width - 1024, camera.VisibleArea.Height - 384);
            spriteBatch.DrawString(font, "Mouse: " + mapEngine.Map.PointToTile(positionMouse + plus).ToString(),
                                   new Vector2(0f, 130f), Color.Red);
            spriteBatch.End();

            //Viewport oldViewport2 = ScreenManager.GraphicsDevice.Viewport;
            //ScreenManager.GraphicsDevice.Viewport = playerTwoViewport;

            twoView.Draw(gameTime);
            //ScreenManager.GraphicsDevice.Viewport = oldViewport2;

            DrawViewportEdges(spriteBatch, playerOneViewport);
            DrawViewportEdges(spriteBatch, playerTwoViewport);

        }

        /// <summary>
        /// A helper to draw the edges of a viewport.
        /// </summary>
        private void DrawViewportEdges(SpriteBatch spriteBatch, Viewport viewport)
        {
            const int edgeWidth = 2;

            // We now compute four rectangles that make up our edges
            Rectangle topEdge = new Rectangle(
                viewport.X - edgeWidth / 2,
                viewport.Y - edgeWidth / 2,
                viewport.Width + edgeWidth,
                edgeWidth);
            Rectangle bottomEdge = new Rectangle(
                viewport.X - edgeWidth / 2,
                viewport.Y + viewport.Height - edgeWidth / 2,
                viewport.Width + edgeWidth,
                edgeWidth);
            Rectangle leftEdge = new Rectangle(
                viewport.X - edgeWidth / 2,
                viewport.Y - edgeWidth / 2,
                edgeWidth,
                viewport.Height + edgeWidth);
            Rectangle rightEdge = new Rectangle(
                viewport.X + viewport.Width - edgeWidth / 2,
                viewport.Y - edgeWidth / 2,
                edgeWidth,
                viewport.Height + edgeWidth);

            // We just use SpriteBatch to draw the four rectangles
            spriteBatch.Begin();
            spriteBatch.Draw(blank, topEdge, Color.Black);
            spriteBatch.Draw(blank, bottomEdge, Color.Black);
            spriteBatch.Draw(blank, leftEdge, Color.Black);
            spriteBatch.Draw(blank, rightEdge, Color.Black);
            spriteBatch.End();
        }


        public void CheckCollision()
        {
        //    Point point = mapEngine.Map.PointToTile(World.Player.Position);
        //    foreach (Portal portal in mapEngine.Map.Portals)
        //    {
        //        if (point == portal.Position)
        //        {
        //            mapEngine = new MapEngine();
        //            mapEngine.Map = new Map();
        //            SpriteBatch spriteBatch = new SpriteBatch(ScreenManager.GraphicsDevice);
        //            String strPath = "Content\\Maps\\" + portal.DestinationMap;
        //            mapEngine.Map = mapEngine.LoadMap(ScreenManager.Game.Content, strPath);
        //            camera = new Camera(new Vector2(mapEngine.Map.MapDimensions.X, mapEngine.Map.MapDimensions.Y), new Vector2(mapEngine.Map.TileSize.X, mapEngine.Map.TileSize.Y), new Vector2(playerOneViewport.Width, playerOneViewport.Height));

        //            World.Player.Position =
        //                new Vector2(portal.DestinationTileLocation.X * mapEngine.Map.TileSize.X,
        //                            portal.DestinationTileLocation.Y * mapEngine.Map.TileSize.Y);

        //            camera.FocusOn(World.Player);

        //            LoadClipMap();
        //        }
        //    }
        }
        private void LoadClipMap()
        {
            World.ClipMap = new Dictionary<Vector2, Rectangle>();

            for (int y = 0; y < mapEngine.Map.MapDimensions.Y; y++)
            {
                for (int x = 0; x < mapEngine.Map.MapDimensions.X; x++)
                {
                    Point mapPosition = new Point(x, y);
                    if (mapEngine.Map.IsBlocked(mapPosition))
                    {
                        World.ClipMap.Add(new Vector2(x, y), new Rectangle(x * mapEngine.Map.TileSize.X, y * mapEngine.Map.TileSize.Y, mapEngine.Map.TileSize.X, mapEngine.Map.TileSize.Y));
                    }


                }
            }
        }
        private void CheckCollisions()
        {
            Point pTileLoc = mapEngine.Map.PointToTile(World.Player.Position);
            World.Player.Bounds = new Rectangle((int)(World.Player.Position.X - (mapEngine.Map.TileSize.X / 2)), (int)(World.Player.Position.Y), mapEngine.Map.TileSize.X - (mapEngine.Map.TileSize.X / 16), mapEngine.Map.TileSize.Y - (mapEngine.Map.TileSize.Y / 16)); ;
            Vector2 key = new Vector2(pTileLoc.X, pTileLoc.Y);
            if (World.ClipMap.ContainsKey(key))
            {
                if (World.Player.Bounds.Intersects(World.ClipMap[key]))
                {
                    World.Player.Collision();
                }
            }
        }
    }
}
